home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / admin / sudo-1.000 / sudo-1 / sudo-1.2 / sudo.c < prev    next >
C/C++ Source or Header  |  1993-12-05  |  5KB  |  241 lines

  1. /*
  2.  *  sudo version 1.1 allows users to execute commands as root
  3.  *  Copyright (C) 1991  The Root Group, Inc.
  4.  *
  5.  *  This program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 1, or (at your option)
  8.  *  any later version.
  9.  *
  10.  *  This program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  *  GNU General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with this program; if not, write to the Free Software
  17.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  *
  19.  *  If you make modifications to the source, we would be happy to have
  20.  *  them to include in future releases.  Feel free to send them to:
  21.  *      Jeff Nieusma                       nieusma@rootgroup.com
  22.  *      3959 Arbol CT                      (303) 447-8093
  23.  *      Boulder, CO 80301-1752             
  24.  *
  25.  **************************************************************************
  26.  *
  27.  *   sudo.c
  28.  *
  29.  *   This is the main() routine for sudo
  30.  *
  31.  *   sudo is a program to allow users to execute commands 
  32.  *   as root.  The commands are defined in a global network-
  33.  *   wide file and can be distributed.
  34.  *
  35.  *   sudo has been hacked far and wide.  Too many people to
  36.  *   know about.  It's about time to come up with a secure
  37.  *   version that will work well in a network.
  38.  *
  39.  *   This most recent version is done by:
  40.  *
  41.  *              Jeff Nieusma <nieusma@rootgroup.com>
  42.  *              Dave Hieb    <davehieb@rootgroup.com>
  43.  */
  44.  
  45. #define MAIN
  46.  
  47. #include <stdio.h>
  48. #include <string.h>
  49. #include <strings.h>
  50. #ifdef LINUX 
  51. #include <sys/types.h>
  52. #endif /* LINUX */
  53. #include <pwd.h>
  54. #include <netdb.h>
  55. #include <sys/param.h>
  56. #include "sudo.h"
  57. extern char *malloc();
  58.  
  59. int  Argc;
  60. char **Argv;
  61. char *host;
  62. char *user;
  63. char *cmnd;
  64. #ifdef MULTIMAX
  65. unsigned short uid;
  66. #else
  67. uid_t uid;
  68. #endif
  69.  
  70.  
  71.  
  72. /********************************************************************
  73.  *
  74.  *  main ()
  75.  *
  76.  *  the driving force behind sudo...
  77.  */
  78.  
  79. main(argc, argv)
  80. int argc; char **argv;
  81. {
  82. static void usage();
  83. int rtn;
  84.  
  85. Argv=argv;
  86. Argc=argc;
  87.  
  88. /* if nothing is passed, we don't need to do anything... */
  89. if ( argc < 2 ) usage();
  90.  
  91. /* close all file descriptors to make sure we have a nice
  92.  * clean slate from which to work.  
  93.  */
  94. for ( rtn = getdtablesize() - 1 ; rtn > 3; rtn -- )
  95.     (void)close(rtn);
  96.  
  97. load_globals();    /* load the user host cmnd and uid variables */
  98.  
  99. if ( setuid(0) ) {
  100.     perror("setuid(0)");
  101.     exit(1);
  102.     }
  103. rtn=validate();
  104. #ifdef LINUX
  105. if ( setreuid(uid) ) {
  106. #else
  107. if ( setruid(uid) ) {
  108. #endif
  109.     perror("setruid(uid)");
  110.     exit(1);
  111.     }
  112.  
  113. switch ( rtn ) {
  114.  
  115.     case VALIDATE_OK:
  116.         check_user();
  117.             log_error( ALL_SYSTEMS_GO );
  118.             if ( setuid(0) ) {
  119.         perror("setuid(0)");
  120.         exit(1);
  121.         }
  122.             execv(cmnd, &Argv[1]);
  123.         break;
  124.         
  125.     case VALIDATE_NO_USER:
  126.     case VALIDATE_NOT_OK: 
  127.     case VALIDATE_ERROR:
  128.     default:
  129.         log_error ( rtn );
  130.         if ( setuid ( uid ) ) {
  131.         perror("setuid(uid)");
  132.         exit(1);
  133.         }
  134.         inform_user ( rtn );
  135.         exit (1);
  136.         break;
  137.  
  138.     }
  139.  
  140.  
  141. }
  142.  
  143.  
  144.  
  145.  
  146.  
  147. /**********************************************************************
  148.  *
  149.  *  load_globals()
  150.  *
  151.  *  This function primes the important global variables:
  152.  *  user, host, cmnd, uid
  153.  */
  154.  
  155. void load_globals()
  156. {
  157. struct passwd *pw_ent;
  158. struct hostent *h_ent;
  159. char path[MAXPATHLEN+1];
  160. char *p;
  161.  
  162.  
  163. if ( (user=malloc(9)) == NULL ) {
  164.     perror ("malloc");
  165.     exit (1);
  166.     }
  167. if ( (host=malloc(MAXHOSTNAMELEN+1)) == NULL ) {
  168.     perror ("malloc");
  169.     exit (1);
  170.     }
  171.  
  172. uid = getuid();            /* we need to tuck this away for safe keeping */
  173.  
  174.  
  175. /* loading the cmnd global variable from argv[1] */
  176.  
  177. strncpy(path, Argv[1], MAXPATHLEN)[MAXPATHLEN] = 0;  
  178. cmnd = find_path ( path );  /* get the absolute path */
  179. if ( cmnd == NULL ) {
  180.     fprintf ( stderr, "%s: %s: command not found\n", Argv[0], Argv[1] );
  181.     exit (1);
  182.     }
  183. cmnd = strdup ( cmnd );
  184.  
  185. #ifdef NO_ROOT_SUDO
  186. if ( uid == 0 ) {
  187.     fprintf(stderr, "You are already root, you don\'t need to use sudo.\n");
  188.     exit (1);
  189.     }
  190. #endif
  191.  
  192. /* loading the user global variable from the passwd file */
  193.  
  194. if ( (pw_ent = getpwuid( uid )) == NULL ) {
  195.     sprintf ( user, "%u", uid );
  196.     log_error( GLOBAL_NO_PW_ENT );
  197.     inform_user ( GLOBAL_NO_PW_ENT );
  198.     exit (1);
  199.     }
  200. strncpy ( user, pw_ent -> pw_name, 8 ) [8] = '\0';
  201.  
  202.  
  203. /* loading the host global variable from gethostname() & gethostbyname() */
  204.  
  205. if (( gethostname ( host, MAXHOSTNAMELEN ))) {
  206.     strcpy ( host, "amnesiac" );
  207.     log_error ( GLOBAL_NO_HOSTNAME );
  208.     inform_user ( GLOBAL_NO_HOSTNAME );
  209.     }
  210. else {
  211.     if ( ( h_ent = gethostbyname ( host) ) == NULL ) 
  212.     log_error ( GLOBAL_HOST_UNREGISTERED );
  213.     else 
  214.     strcpy ( host, h_ent -> h_name );
  215.  
  216. /* We don't want to return the fully quallified name all the time...  */
  217.  
  218. #ifndef FQDN
  219.     if ( (p = index ( host, '.' )) ) *p='\0';
  220. #endif
  221.     }
  222.  
  223. }
  224.  
  225.  
  226.  
  227.  
  228. /**********************************************************************
  229.  *
  230.  * usage()
  231.  *
  232.  *  this function just gives you instructions and exits
  233.  */
  234.  
  235. static void usage()
  236. {
  237. fprintf( stderr, "usage: %s command\n", *Argv);
  238. exit (1);
  239. }
  240.  
  241.